﻿using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public interface ISpecialModuleContentPage
	{
		string ContentPage { get; set; }
	}

	/// <summary>
	/// 专题模块解析器。
	/// </summary>
	public interface ISpecialModuleParser
	{
		string ParsePreviewPart(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, SpecialPageConfiguration configuration, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page);
		string ParsePreviewContent(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page, string moduleView);

		string ParsePart(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, SpecialPageConfiguration configuration, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page);
		string ParseContent(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page);
	}

	/// <summary>
	/// 专题模块接口。
	/// </summary>
	public interface ISpecialModule : ISpecialModuleParser
	{
		bool ExistsModule(int siteId, int specialId, string moduleCode);
		string CreateModule(int siteId, int specialId, string moduleCode, string moduleName);
		void UpdateModule(int siteId, int specialId, string refModuleId, string newName);
		void DeleteModule(int siteId, int specialId, string refModuleId);
		Guid? GetResourceId(int siteId, int specialId, string moduleCode, string refModuleId);
		Resources.CodeId GetResourceCodeId(int siteId, int specialId, string moduleCode, string refModuleId);

		string ModuleType { get; set; }
		string GetAccreditUrlPattern(Special special);
		string GetManageUrlPattern(Special special);
		string GetContentConfigurationUrlPattern(Special special);
		string GetPageConfigurationUrlPattern(Special special);

		string SerializeContentConfiguration(object config);
		object DeserializeContentConfiguration(string config);
		string SerializePageConfiguration(SpecialPageConfiguration config);
		SpecialPageConfiguration DeserializePageConfiguration(string config);
	}




	/// <summary>
	/// 专题模块助手类。
	/// </summary>
	public static class SpecialModuleHelper
	{
		private static LoadedValue<Dictionary<string, SpecialModuleElement>> specialModuleConfigurationsLoaded;
		/// <summary>
		/// 专题模块配置。
		/// </summary>
		public static Dictionary<string, SpecialModuleElement> SpecialModuleConfigurations
		{
			get
			{
				if (specialModuleConfigurationsLoaded.Loader == null)
					specialModuleConfigurationsLoaded.Loader = () =>
						{
							SpecialModuleElementCollection specialModules = ApplicationConfiguration.GetSpecialModules();
							if (specialModules == null) return null;
							Dictionary<string, SpecialModuleElement> mcs = new Dictionary<string, SpecialModuleElement>();
							foreach (SpecialModuleElement specialModule in specialModules)
							{
								mcs[specialModule.ModuleType] = specialModule;
							}
							return mcs;
						};

				return specialModuleConfigurationsLoaded.Value;
			}
		}




		private static LoadedValue<Dictionary<string, ISpecialModule>> specialModulesLoaded;
		/// <summary>
		/// 专题模块集合。
		/// </summary>
		public static Dictionary<string, ISpecialModule> SpecialModules
		{
			get
			{
				if (specialModulesLoaded.Loader == null)
					specialModulesLoaded.Loader = () =>
						{
							if (SpecialModuleConfigurations == null) return null;
							Dictionary<string, ISpecialModule> sms = new Dictionary<string, ISpecialModule>();
							foreach (var mc in SpecialModuleConfigurations.Values)
							{
								Assembly assembly = null;
								if (string.IsNullOrEmpty(mc.Assembly))
									assembly = Assembly.GetCallingAssembly();
								else
									assembly = Assembly.Load(mc.Assembly);
								sms[mc.ModuleType] = (ISpecialModule)assembly.CreateInstance(mc.ClassName);
								sms[mc.ModuleType].ModuleType = mc.ModuleType;
							}
							return sms;
						};

				return specialModulesLoaded.Value;
			}
		}




		/// <summary>
		/// 验证指定模块类别是否存在指定的模块。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>布尔值表示指定的模块类别是否存在指定的模块。</returns>
		public static bool ExistsModule(string moduleType, int siteId, int specialId, string moduleCode)
		{
			return SpecialModules[moduleType].ExistsModule(siteId, specialId, moduleCode);
		}



		/// <summary>
		/// 创建指定模块类别的模块。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <param name="moduleName">模块的名称。</param>
		/// <returns>模块的标识。</returns>
		public static string CreateModule(string moduleType, int siteId, int specialId, string moduleCode, string moduleName)
		{
			return SpecialModules[moduleType].CreateModule(siteId, specialId, moduleCode, moduleName);
		}


		
		/// <summary>
		/// 更新指定的模块类别的模块。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="refModuleId">引用模块的标识。</param>
		/// <param name="newName">新的模块的名称。</param>
		public static void UpdateModule(string moduleType, int siteId, int specialId, string refModuleId, string newName)
		{
			SpecialModules[moduleType].UpdateModule(siteId, specialId, refModuleId, newName);
		}



		/// <summary>
		/// 删除指定模块类别的模块。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="refModuleId">引用模块的标识。</param>
		public static void DeleteModule(string moduleType, int siteId, int specialId, string refModuleId)
		{
			SpecialModules[moduleType].DeleteModule(siteId, specialId, refModuleId);
		}



		/// <summary>
		/// 获取指定模块类别的权限资源标识。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <param name="refModuleId">引用模块的标识。</param>
		/// <returns>指定模块类别的权限资源标识。</returns>
		public static Guid? GetResourceId(string moduleType, int siteId, int specialId, string moduleCode, string refModuleId)
		{
			return SpecialModules[moduleType].GetResourceId(siteId, specialId, moduleCode, refModuleId);
		}



		/// <summary>
		/// 获取指定模块类别的权限资源标识。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="siteId">模块的站点标识。</param>
		/// <param name="specialId">模块所属的专题。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <param name="refModuleId">引用模块的标识。</param>
		/// <returns>指定模块类别的权限资源标识。</returns>
		public static Resources.CodeId GetResourceCodeId(string moduleType, int siteId, int specialId, string moduleCode, string refModuleId)
		{
			return SpecialModules[moduleType].GetResourceCodeId(siteId, specialId, moduleCode, refModuleId);
		}




		/// <summary>
		/// 序列化指定模块类别的内容配置。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="configuration">内容配置对象。</param>
		/// <returns>序列化的字符串。</returns>
		public static string SerializeContentConfiguration(string moduleType, object config)
		{
			return SpecialModules[moduleType].SerializeContentConfiguration(config);
		}



		/// <summary>
		/// 反序列化指定模块类别的内容配置。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="config">内容配置字符串。</param>
		/// <returns>序列化的对象。</returns>
		public static object DeserializeContentConfiguration(string moduleType, string config)
		{
			return SpecialModules[moduleType].DeserializeContentConfiguration(config);
		}



		/// <summary>
		/// 序列化指定模块类别的页配置。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="configuration">页配置对象。</param>
		/// <returns>序列化的字符串。</returns>
		public static string SerializePageConfiguration(string moduleType, SpecialPageConfiguration config)
		{
			return SpecialModules[moduleType].SerializePageConfiguration(config);
		}



		/// <summary>
		/// 反序列化指定模块类别的页配置。
		/// </summary>
		/// <param name="moduleType">指定的模块类别。</param>
		/// <param name="config">页配置字符串。</param>
		/// <returns>序列化的对象。</returns>
		public static SpecialPageConfiguration DeserializePageConfiguration(string moduleType, string config)
		{
			return SpecialModules[moduleType].DeserializePageConfiguration(config);
		}




		/// <summary>
		/// 解析区块预览Html。
		/// </summary>
		/// <param name="module">指定的模块。</param>
		/// <param name="configuration">区块配置。</param>
		/// <param name="specialCode">专题代码。</param>
		/// <returns>解析的预览Html。</returns>
		public static string ParsePreviewPart(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, SpecialPageConfiguration configuration, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page)
		{
			page.ModuleCounter++;
			return SpecialModules[module.ModuleType].ParsePreviewPart(templateConfiguration, module, configuration, specialInfo, pageInfo, ref page);
		}

		/// <summary>
		/// 解析模块内容预览Html。
		/// </summary>
		/// <param name="module">指定的模块。</param>
		/// <param name="specialCode">专题代码。</param>
		/// <returns>解析的预览Html。</returns>
		public static string ParsePreviewContent(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page, string moduleView)
		{
			page.ModuleCounter++;
			return SpecialModules[module.ModuleType].ParsePreviewContent(templateConfiguration, module, specialInfo, pageInfo, ref page, moduleView);
		}
		
		/// <summary>
		/// 解析区块Html。
		/// </summary>
		/// <param name="module">指定的模块。</param>
		/// <param name="configuration">区块配置。</param>
		/// <param name="specialCode">专题代码。</param>
		/// <returns>解析的Html。</returns>
		public static string ParsePart(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, SpecialPageConfiguration configuration, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page)
		{
			page.ModuleCounter++;
			return SpecialModules[module.ModuleType].ParsePart(templateConfiguration, module, configuration, specialInfo, pageInfo, ref page);
		}

		/// <summary>
		/// 解析模块内容Html。
		/// </summary>
		/// <param name="module">指定的模块。</param>
		/// <param name="specialCode">专题代码。</param>
		/// <returns>解析的Html。</returns>
		public static string ParseContent(SpecialTemplateConfiguration templateConfiguration, SpecialModule module, Special specialInfo, SpecialPage pageInfo, ref SpecialPageInfo page)
		{
			page.ModuleCounter++;
			return SpecialModules[module.ModuleType].ParseContent(templateConfiguration, module, specialInfo, pageInfo, ref page);
		}
	}




	public partial class SpecialModule : ICreator
	{
		/// <summary>
		/// 内容配置对象。
		/// </summary>
		public object ContentConfigurationObject
		{
			get
			{
				return SpecialModuleHelper.DeserializeContentConfiguration(ModuleType, ContentConfiguration);
			}
			set
			{
				ContentConfiguration = SpecialModuleHelper.SerializeContentConfiguration(ModuleType, value);
			}
		}
	}




	/// <summary>
	/// SpecialModules 类。
	/// </summary>
	public static partial class SpecialModules
	{
		public const string INFO_TYPE = "SpecialModule";



		#region GetIdentifier
		/// <summary>
		/// 根据指定的信息获取专题模块标识。
		/// </summary>
		/// <param name="o">专题模块的集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>指定的专题模块标识。</returns>
		internal static int? GetIdentifier(this System.Data.Linq.Table<SpecialModule> o, int specialId, string moduleCode)
		{
			return (from p in o
					where p.SpecialId == specialId && p.ModuleCode == moduleCode
					select (int?)p.ModuleId).SingleOrDefault();
		}

		/// <summary>
		/// 根据指定的信息获取专题模块标识。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>指定的专题模块标识。</returns>
		public static int? GetIdentifier(int specialId, string moduleCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.GetIdentifier(specialId, moduleCode);
		}
		#endregion




		#region GetItem
		/// <summary>
		/// 根据标识获取指定的专题模块。
		/// </summary>
		/// <param name="o">专题模块集合。</param>
		/// <param name="moduleId">获取的专题模块标识 ModuleId。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialModule GetItem(this System.Data.Linq.Table<SpecialModule> o, int moduleId)
		{
			return o.SingleOrDefault(p => p.ModuleId == moduleId);
		}

		/// <summary>
		/// 根据标识获取指定的专题模块。
		/// </summary>
		/// <param name="moduleId">获取的专题模块标识 ModuleId。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialModule GetItem(int moduleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.GetItem(moduleId);
		}




		/// <summary>
		/// 根据标识获取指定的专题模块。
		/// </summary>
		/// <param name="o">专题模块集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialModule GetItem(this System.Data.Linq.Table<SpecialModule> o, int specialId, string moduleCode)
		{
			return o.SingleOrDefault(p => p.SpecialId == specialId && p.ModuleCode == moduleCode);
		}

		/// <summary>
		/// 根据标识获取指定的专题模块。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>获取的信息项。</returns>
		public static SpecialModule GetItem(int specialId, string moduleCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.GetItem(specialId, moduleCode);
		}




		/// <summary>
		/// 根据模块类型及引用模块ID获取指定的模块。
		/// </summary>
		/// <param name="o">专题模块集合。</param>
		/// <param name="moduleType">模块类别。</param>
		/// <param name="moduleId">模块标识。</param>
		/// <returns>指定的模块。</returns>
		public static SpecialModule GetItemByRefModuleId(this System.Data.Linq.Table<SpecialModule> o, string moduleType, string moduleId)
		{
			return o.FirstOrDefault(p => p.ModuleType == moduleType && p.RefModuleId == moduleId);
		}

		/// <summary>
		/// 根据模块类型及引用模块ID获取指定的模块。
		/// </summary>
		/// <param name="moduleType">模块类别。</param>
		/// <param name="moduleId">模块标识。</param>
		/// <returns>指定的模块。</returns>
		public static SpecialModule GetItemByRefModuleId(string moduleType, string moduleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.GetItemByRefModuleId(moduleType, moduleId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的专题模块是否已经存在。
		/// </summary>
		/// <param name="o">专题模块集合。</param>
		/// <param name="moduleId">验证的专题模块标识 ModuleId。</param>
		/// <returns>布尔值表示指定的专题模块是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<SpecialModule> o, int moduleId)
		{
			return o.Any(p => p.ModuleId == moduleId);
		}

		/// <summary>
		/// 验证指定的专题模块是否已经存在。
		/// </summary>
		/// <param name="moduleId">验证的专题模块标识 ModuleId。</param>
		/// <returns>布尔值表示指定的专题模块是否已经存在。</returns>
		public static bool Exists(int moduleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.Exists(moduleId);
		}




		/// <summary>
		/// 验证指定的专题模块是否已经存在。
		/// </summary>
		/// <param name="o">专题模块集合。</param>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>布尔值表示指定的专题模块是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<SpecialModule> o, int specialId, string moduleCode)
		{
			return o.Any(p => p.SpecialId == specialId && p.ModuleCode == moduleCode);
		}

		/// <summary>
		/// 验证指定的专题模块是否已经存在。
		/// </summary>
		/// <param name="specialId">所属专题标识。</param>
		/// <param name="moduleCode">模块代码。</param>
		/// <returns>布尔值表示指定的专题模块是否已经存在。</returns>
		public static bool Exists(int specialId, string moduleCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.SpecialModules.Exists(specialId, moduleCode);
		}
		#endregion
	}



	/// <summary>
	/// SpecialModules 类操作部分。
	/// </summary>
	public static partial class SpecialModules
	{
		#region Insert
		/// <summary>
		/// 添加专题模块。
		/// </summary>
		/// <param name="insertedSpecialModule">添加的专题模块。</param>
		/// <returns>添加的专题模块。</returns>
		public static SpecialModule Insert(SpecialModule insertedSpecialModule)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialModule specialModule = insertedSpecialModule.ToNewEntity<SpecialModule>();
			specialModule.CreatorId = Users.CurrentUserId;
			specialModule.CreationDate = DateTime.Now;

			GetInsertRight(dc, specialModule, true);	// 权限验证

			// 获取相关专题信息
			Special special = dc.Specials.GetItem(insertedSpecialModule.SpecialId);
			if (special == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);
			// 验证模块是否存在
			if (SpecialModuleHelper.ExistsModule(insertedSpecialModule.ModuleType, special.SiteId, insertedSpecialModule.SpecialId, insertedSpecialModule.ModuleCode)
				|| Exists(insertedSpecialModule.SpecialId, insertedSpecialModule.ModuleCode))
				throw new ObjectExistsException(Res.Validate_ObjectExists);
			// 创建模块
			string refModuleId = SpecialModuleHelper.CreateModule(insertedSpecialModule.ModuleType, special.SiteId, insertedSpecialModule.SpecialId, insertedSpecialModule.ModuleCode, insertedSpecialModule.ModuleName);
			specialModule.RefModuleId = refModuleId;

			dc.SpecialModules.InsertOnSubmit(specialModule);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialModule.ModuleId.ToString(), "Insert", specialModule.ModuleType + "/" + specialModule.RefModuleId + ":" + specialModule.ModuleName);

			// 返回只读数据
			return insertedSpecialModule.FillByEntity(specialModule);
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedColumns = typeof(SpecialModule).GetEntityColumnNames(new string[] {
				"ModuleName",
				"BelongPage"
			}, true);

		/// <summary>
		/// 修改专题模块。
		/// </summary>
		/// <param name="updatedSpecialModule">修改的专题模块。</param>
		/// <returns>修改的专题模块。</returns>
		public static SpecialModule Update(SpecialModule updatedSpecialModule)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialModule specialModule = dc.SpecialModules.GetItem(updatedSpecialModule.ModuleId);
			if (specialModule == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialModule, true);	// 权限验证

			// 获取相关专题信息
			Special special = dc.Specials.GetItem(updatedSpecialModule.SpecialId);
			// 更新模块
			SpecialModuleHelper.UpdateModule(specialModule.ModuleType, special.SiteId, specialModule.SpecialId, specialModule.RefModuleId, updatedSpecialModule.ModuleName);

			specialModule.FillByEntity(updatedSpecialModule, EntityColumnsSetType.Limit, _updatedColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialModule.ModuleId.ToString(), "Update", specialModule.ModuleType + "/" + specialModule.RefModuleId + ":" + specialModule.ModuleName);

			// 返回只读数据
			return updatedSpecialModule.FillByEntity(specialModule);
		}

		/// <summary>
		/// 修改模块名称。
		/// </summary>
		/// <param name="moduleId">要修改的模块标识。</param>
		/// <param name="moduleName">修改的名称。</param>
		public static void UpdateModuleName(int moduleId, string moduleName)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialModule specialModule = dc.SpecialModules.GetItem(moduleId);
			if (specialModule == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, specialModule, true);	// 权限验证

			// 获取相关专题信息
			Special special = specialModule.Special;
			// 更新模块
			SpecialModuleHelper.UpdateModule(specialModule.ModuleType, special.SiteId, specialModule.SpecialId, specialModule.RefModuleId, moduleName);

			specialModule.ModuleName = moduleName;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialModule.ModuleId.ToString(), "Update/ModuleName", specialModule.ModuleType + "/" + specialModule.RefModuleId + ":" + specialModule.ModuleName);

			return;
		}
		#endregion



		#region UpdateContentConfiguration
		/// <summary>
		/// 修改模块内容配置。
		/// </summary>
		/// <param name="moduleId">要修改的模块标识。</param>
		/// <param name="configuration">修改的配置。</param>
		public static void UpdateContentConfiguration(int moduleId, object configuration)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialModule module = dc.SpecialModules.GetItem(moduleId);
			if (module == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, module, true);	// 权限验证

			module.ContentConfigurationObject = configuration;

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, module.ModuleId.ToString(), "Update/ContentConfiguration", module.ModuleType + "/" + module.RefModuleId + ":" + module.ModuleName);

			return;
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除专题模块。
		/// </summary>
		/// <param name="moduleId">删除的专题模块标识 ModuleId。</param>
		public static void Delete(int moduleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			SpecialModule specialModule = dc.SpecialModules.GetItem(moduleId);
			if (specialModule == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, specialModule, true);	// 权限验证

			Delete(dc, specialModule);

			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, null, null, INFO_TYPE, specialModule.ModuleId.ToString(), "Delete", specialModule.ModuleType + "/" + specialModule.RefModuleId + ":" + specialModule.ModuleName);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, SpecialModule specialModule)
		{
			// 获取相关专题信息
			Special special = dc.Specials.GetItem(specialModule.SpecialId);
			// 删除模块
			SpecialModuleHelper.DeleteModule(specialModule.ModuleType, special.SiteId, specialModule.SpecialId, specialModule.RefModuleId);

			dc.SpecialModules.DeleteOnSubmit(specialModule);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, Special parent)
		{
			IEnumerable<SpecialModule> e = parent.SpecialModules.AsEnumerable();
			foreach (SpecialModule i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// SpecialModules 类对应操作权限部分。
	/// </summary>
	public static partial class SpecialModules
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加专题模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialModule">添加的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加专题模块的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, SpecialModule specialModule, bool triggerException)
		{
			Special special = Specials.GetItem(specialModule.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加专题模块的权限。
		/// </summary>
		/// <param name="specialModule">添加的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加专题模块的权限。</returns>
		public static bool GetInsertRight(SpecialModule specialModule, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), specialModule, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加专题模块的权限。
		/// </summary>
		/// <param name="specialModule">添加的专题模块对象。</param>
		/// <returns>布尔值表示当前用户是否有添加专题模块的权限。</returns>
		public static bool GetInsertRight(SpecialModule specialModule)
		{
			return GetInsertRight(specialModule, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新专题模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialModule">更新的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新专题模块的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, SpecialModule specialModule, bool triggerException)
		{
			Special special = Specials.GetItem(specialModule.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新专题模块的权限。
		/// </summary>
		/// <param name="specialModule">更新的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新专题模块的权限。</returns>
		public static bool GetUpdateRight(SpecialModule specialModule, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), specialModule, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新专题模块的权限。
		/// </summary>
		/// <param name="specialModule">更新的专题模块对象。</param>
		/// <returns>布尔值表示当前用户是否有更新专题模块的权限。</returns>
		public static bool GetUpdateRight(SpecialModule specialModule)
		{
			return GetUpdateRight(specialModule, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除专题模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="specialModule">删除的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除专题模块的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, SpecialModule specialModule, bool triggerException)
		{
			Special special = Specials.GetItem(specialModule.SpecialId);
			return Specials.GetUpdateRight(dc, special, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除专题模块的权限。
		/// </summary>
		/// <param name="specialModule">删除的专题模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除专题模块的权限。</returns>
		public static bool GetDeleteRight(SpecialModule specialModule, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), specialModule, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除专题模块的权限。
		/// </summary>
		/// <param name="specialModule">删除的专题模块对象。</param>
		/// <returns>布尔值表示当前用户是否有删除专题模块的权限。</returns>
		public static bool GetDeleteRight(SpecialModule specialModule)
		{
			return GetDeleteRight(specialModule, false);
		}
		#endregion
	}



	/// <summary>
	/// SpecialModules 类后台管理部分。
	/// </summary>
	public static partial class SpecialModules
	{
		private static IQueryable<SpecialModule> GetManageListQuery(GenericModuleDataContext dc, int? specialId, string keyword)
		{
			IQueryable<SpecialModule> q;

			q = from p in dc.SpecialModules
				orderby p.ModuleType, p.CreationDate descending
				select p;

			if (specialId.HasValue)
				q = q.Where(p => p.SpecialId == specialId.Value);

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.ModuleCode.Contains(keyword) || p.ModuleName.Contains(keyword));

			return q;
		}

		public static PaginationInfo<List<SpecialModule>> GetPaginationManageList(int? specialId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetManageListQuery(dc, specialId, keyword);

			PaginationInfo<List<SpecialModule>> pageInfo = new PaginationInfo<List<SpecialModule>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<SpecialModule> GetManageList(int? specialId, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetManageListQuery(dc, specialId, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}
	}
}